package com.rc.saas.mini.service.order;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.rc.saas.mini.mapper.elec.ElecGunMapper;
import com.rc.saas.mini.mapper.elec.ElecStationMapper;
import com.rc.saas.mini.mapper.enterprise.EnterpriseMemberMapper;
import com.rc.saas.mini.mapper.order.OrderInfoMapper;
import com.rc.saas.mini.mapper.ugs.UgsMemberLevelRecordMapper;
import com.rc.saas.mini.model.elec.ElecGun;
import com.rc.saas.mini.model.elec.ElecGunExample;
import com.rc.saas.mini.model.elec.ElecStation;
import com.rc.saas.mini.model.elec.ElecStationExample;
import com.rc.saas.mini.model.enterprise.EnterpriseMember;
import com.rc.saas.mini.model.enterprise.EnterpriseMemberExample;
import com.rc.saas.mini.model.member.MemberInfo;
import com.rc.saas.mini.model.member.MemberInfoExample;
import com.rc.saas.mini.model.order.OrderInfo;
import com.rc.saas.mini.model.order.OrderInfoExample;
import com.rc.saas.mini.model.rc.RcEvaluate;
import com.rc.saas.mini.service.elec.ElecGunService;
import com.rc.saas.mini.service.member.MemberInfoService;
import com.rc.saas.mini.vo.invoice.ElecInvoiceVo;
import com.rc.saas.mini.vo.order.OrderStatisticsVo;
import com.rc.saas.mini.vo.order.OrderInfoVo;
import com.rc.saas.mini.vo.rc.RcWithEvaluateVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author wangzhengwei
 * @create 2021/12/16
 */
@Service
public class OrderInfoServiceImpl implements OrderInfoService {

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private UgsMemberLevelRecordMapper ugsMemberLevelRecordMapper;

    @Autowired
    private MemberInfoService memberInfoService;

    @Autowired
    private ElecStationMapper elecStationMapper;

    @Autowired
    private ElecGunMapper elecGunMapper;

    @Autowired
    private EnterpriseMemberMapper enterpriseMemberMapper;

    @Autowired
    private ElecGunService elecGunService;

    @Override
    public OrderInfoMapper getMapper() {
        return orderInfoMapper;
    }

    @Override
    public OrderStatisticsVo countOrderByYearMonth(MemberInfo member, String yearMonth) {
        SimpleDateFormat format=new SimpleDateFormat("yyyy-MM");
        if(yearMonth==null){
            yearMonth=format.format(Calendar.getInstance().getTime());
        }
        OrderStatisticsVo orderStatisticsVo = orderInfoMapper.countOrderByYearMonth(member.getMemberId(), yearMonth);
        Integer value = ugsMemberLevelRecordMapper.countGrowthValueByYearMonth(member.getMemberId(), yearMonth);
        orderStatisticsVo.setGrowthValue(value);
        return orderStatisticsVo;
    }

    @Override
    public OrderInfo selectLastByMember(Long memberId, String tenantCode) {
        OrderInfoExample orderExample = new OrderInfoExample();
        orderExample.createCriteria().andMemberIdEqualTo(memberId).andTenantCodeEqualTo(tenantCode);
        orderExample.setOrderByClause("order_id desc LIMIT 1");
        return orderInfoMapper.selectByExample(orderExample).stream().findFirst().orElseGet(() -> null);
    }

    @Override
    public Long countElecOrder(Long memberId, String tenantCode) {
        OrderInfoExample example = new OrderInfoExample();
        example.createCriteria().andTenantCodeEqualTo(tenantCode).andMemberIdEqualTo(memberId).andStatusEqualTo("1");
        Long count = orderInfoMapper.countByExample(example);
        return count;
    }

    @Override
    public List<OrderInfoVo> listOrderByYearMonth(MemberInfo member, String yearMonth, String accountType, String carNumes, String status) {
        List<String> carNumList = new ArrayList<String>();
        if (StringUtils.isNotBlank(carNumes)) {
            String[] carNumArr = carNumes.split(",");

            if (carNumArr != null && carNumArr.length > 0) {
                Collections.addAll(carNumList, carNumArr);
            }
        }
        return orderInfoMapper.listOrderByYearMonth(member.getMemberId(), yearMonth, accountType, carNumList, status);
    }

    @Override
    public PageInfo<String> listPageYearMonthByMemberId(Long memberId, String accountType, String carNumes, Integer pageNo, Integer pageSize, String status) {
        PageHelper.startPage(pageNo, pageSize);
        List<String> carNumList = new ArrayList<String>();
        if (StringUtils.isNotBlank(carNumes)) {
            String[] carNumArr = carNumes.split(",");

            if (carNumArr != null && carNumArr.length > 0) {
                Collections.addAll(carNumList, carNumArr);
            }
        }
        List<String> list = orderInfoMapper.listYearMonthByMemberId(memberId, accountType, carNumList, status);
        return new PageInfo<>(list);
    }

    @Override
    public OrderInfo selectOrderByGunIdAndMember(Long gunId, Long memberId, String tenantCode) {
        //充电中订单
        OrderInfoExample orderExample = new OrderInfoExample();
        orderExample.createCriteria().andMemberIdEqualTo(memberId).andTenantCodeEqualTo(tenantCode).andElecGunIdEqualTo(gunId).andStatusEqualTo("1");
        List<OrderInfo> orders = orderInfoMapper.selectByExample(orderExample);
        if (orders != null && orders.size() > 0) {
            return orders.get(0);
        } else {
            return null;
        }
    }

    @Override
    public List<OrderInfo> listPageOrder(Integer pageNo, Integer pageSize, Long memberId, String startDate, String endDate, String carNum, String memberType) {
        List<Long> memberidList = new ArrayList<>();
        if ("1".equals(memberType)) {
            MemberInfoExample example = new MemberInfoExample();
            example.createCriteria().andEnterpriseMemberIdEqualTo(memberId);
            memberidList = memberInfoService.selectByExample(example).stream().map(MemberInfo::getMemberId).collect(Collectors.toList());
        }
        memberidList.add(memberId);

        PageHelper.startPage(pageNo, pageSize);
        List<OrderInfo> list = orderInfoMapper.listOrder(startDate, endDate, carNum, memberidList);
        return list;
    }

    @Override
    public OrderInfo selectOrderByOutOrderNum(String outOrderNum, String tenantCode) {
        OrderInfoExample example = new OrderInfoExample();
        example.createCriteria().andTenantCodeEqualTo(tenantCode).andOutOrderNumEqualTo(outOrderNum);
        OrderInfo orderInfo = orderInfoMapper.selectByExample(example).stream().findFirst().orElseGet(() -> null);
        return orderInfo;
    }

    @Override
    public OrderInfo selectOrderByOutOrderNum(String outOrderNum) {
        OrderInfoExample example = new OrderInfoExample();
        example.createCriteria().andOutOrderNumEqualTo(outOrderNum);
        OrderInfo orderInfo = orderInfoMapper.selectByExample(example).stream().findFirst().orElseGet(() -> null);
        return orderInfo;
    }

    @Override
    public OrderInfo selectOrderByOrderNum(String orderNum) {
        OrderInfoExample example = new OrderInfoExample();
        example.createCriteria().andOrderNumEqualTo(orderNum);
        OrderInfo orderInfo = orderInfoMapper.selectByExample(example).stream().findFirst().orElseGet(() -> null);
        return orderInfo;
    }

    @Override
    public OrderInfoVo selectOrderById(Long orderId) {
        return orderInfoMapper.selectOrderById(orderId);
    }

    @Override
    public List<OrderInfo> listElecOrder(MemberInfo member, int hours) {
        OrderInfoExample example = new OrderInfoExample();
        Long sub = System.currentTimeMillis() - hours * 60 * 60 * 1000;
        Date date = new Date(sub);
        example.createCriteria().andMemberIdEqualTo(member.getMemberId()).andCreatedTimeGreaterThan(date)
                .andStatusEqualTo("1");
        example.setOrderByClause("created_time desc");
        return orderInfoMapper.selectByExample(example);
    }

    @Override
    public PageInfo<OrderInfoVo> listPageOrderWithoutInvoice(Long memberId, Integer pageNo, Integer pageSize) {
        PageHelper.startPage(pageNo, pageSize);
        List<OrderInfoVo> list = orderInfoMapper.listOrderWithoutInvoice(memberId);
        return new PageInfo<>(list);
    }

    @Override
    public ElecInvoiceVo countInvoiceByOrder(List<Long> selfOrderIds, String tenantCode) {
        return orderInfoMapper.countInvoiceByOrder(selfOrderIds, tenantCode);
    }

    @Override
    public List<OrderInfo> listChargingOrder(Long memberId, Integer hours, String tenantCode) {
        OrderInfoExample example = new OrderInfoExample();
        Long sub = System.currentTimeMillis() - hours * 60 * 60 * 1000;
        Date date = new Date(sub);
        OrderInfoExample.Criteria criteria1 = example.createCriteria();
        criteria1.andMemberIdEqualTo(memberId).andCreatedTimeGreaterThan(date)
                .andStatusEqualTo("1").andTenantCodeEqualTo(tenantCode);
        example.setOrderByClause("created_time desc");
        List<OrderInfo> orders = orderInfoMapper.selectByExample(example);
        orders = orders.stream().filter(orderInfo -> !"5".equals(orderInfo.getHlhtOrderStatus())).collect(Collectors.toList());
        for (OrderInfo order : orders) {
            //订单补充桩群名
            ElecStationExample elecStationExample = new ElecStationExample();
            elecStationExample.createCriteria().andTenantCodeEqualTo(order.getTenantCode()).andElecStationIdEqualTo(order.getElecStationId());
            List<ElecStation> elecStations = elecStationMapper.selectByExample(elecStationExample);
            if (elecStations.size() > 0 && elecStations != null) {
                order.setElecStationName(elecStations.get(0).getStationName());
                order.setAddress(elecStations.get(0).getAddress());

            }
            //订单补充枪编号
            ElecGunExample elecGunExample = new ElecGunExample();
            elecGunExample.createCriteria().andTenantCodeEqualTo(order.getTenantCode()).andElecGunIdEqualTo(order.getElecGunId());
            List<ElecGun> elecGuns = elecGunMapper.selectByExample(elecGunExample);
            if (elecGuns.size() > 0 && elecGuns != null) {
                order.setGunNo(elecGuns.get(0).getGunNo());
            }
        }
        return orders;
    }

    @Override
    public List<String> listEntOrderDateWithoutInvoice(MemberInfo memberInfo) {
        EnterpriseMemberExample example = new EnterpriseMemberExample();
        example.createCriteria().andMemberIdEqualTo(memberInfo.getMemberId());
        EnterpriseMember enterpriseMember = enterpriseMemberMapper.selectByExample(example).stream().findFirst().orElseGet(() -> null);
        List<String> list = orderInfoMapper.listEntOrdertDateRecord(memberInfo, enterpriseMember);
        return list;
    }

    @Override
    public PageInfo<OrderInfoVo> listPageEntOrderWithoutInvoiceByMember(MemberInfo member, String yearMonth, Integer pageNo, Integer pageSize) {
        Long enterpriseId = null;
        EnterpriseMemberExample enterpriseMemberExample = new EnterpriseMemberExample();
        enterpriseMemberExample.createCriteria().andMemberIdEqualTo(member.getMemberId());
        EnterpriseMember enterpriseMember = enterpriseMemberMapper.selectByExample(enterpriseMemberExample).stream().findFirst().orElseGet(() -> null);
        if (enterpriseMember != null) {
            enterpriseId = enterpriseMember.getEnterpriseId();
        }

        PageHelper.startPage(pageNo, pageSize);
        List<OrderInfoVo> list = orderInfoMapper.listEntOrderWithoutInvoiceByMember(member.getTenantCode(), member.getMemberId(), enterpriseId, yearMonth);
        if (list.size() > 0) {
            //去重查找elecGunId
            Set<Long> set = list.stream().filter(orderInfo -> orderInfo.getElecGunId() != null).map(OrderInfo::getElecGunId).collect(Collectors.toSet());
            ElecGunExample elecGunExample = new ElecGunExample();
            elecGunExample.createCriteria().andElecGunIdIn(new ArrayList<>(set));
            List<ElecGun> guns = elecGunService.selectByExample(elecGunExample);
            list.forEach(orderInfoVo -> {
                String gunNo = guns.stream().filter(gun -> orderInfoVo.getElecGunId().equals(gun.getElecGunId())).map(ElecGun::getGunNo).findFirst().orElseGet(() -> null);
                orderInfoVo.setGunNo(gunNo);
            });
        }
        return new PageInfo<>(list);
    }

    @Override
    public List<String> listOrderDateWithInvoice(MemberInfo member, Long invoiceApplyId) {
        return orderInfoMapper.listOrderDateWithInvoice(invoiceApplyId);
    }

    @Override
    public BigDecimal countEntOrderWithoutInvoiceAmountByMember(MemberInfo member, String yearMonth) {
        Long enterpriseId = null;
        EnterpriseMemberExample enterpriseMemberExample = new EnterpriseMemberExample();
        enterpriseMemberExample.createCriteria().andMemberIdEqualTo(member.getMemberId());
        EnterpriseMember enterpriseMember = enterpriseMemberMapper.selectByExample(enterpriseMemberExample).stream().findFirst().orElseGet(() -> null);
        if (enterpriseMember != null) {
            enterpriseId = enterpriseMember.getEnterpriseId();
        }

        List<OrderInfoVo> list = orderInfoMapper.listEntOrderWithoutInvoiceByMember(member.getTenantCode(), member.getMemberId(), enterpriseId, yearMonth);
        Optional<BigDecimal> sumAmount = Optional.ofNullable(list.stream().map(OrderInfoVo::getPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
        return sumAmount.get();
    }

    @Override
    public PageInfo<OrderInfoVo> listPageOrderWithInvovice(MemberInfo member, String yearMonth, Long invoiceApplyId, Integer pageNo, Integer pageSize) {
        PageHelper.startPage(pageNo, pageSize);
        List<OrderInfoVo> list = orderInfoMapper.listOrderWithInvoice(invoiceApplyId, yearMonth);
        return new PageInfo<>(list);
    }

    @Override
    public List<OrderInfo> listOrderRecently(Long memberId) {
        PageHelper.startPage(1, 100);
        OrderInfoExample example = new OrderInfoExample();
        example.createCriteria().andMemberIdEqualTo(memberId);
        example.setOrderByClause("created_time desc");
        List<OrderInfo> list = orderInfoMapper.selectByExample(example);
        return list;
    }

    @Override
    public List<OrderInfoVo> listPageByRcEvaluateWithOrder(Long memberId) {
        return orderInfoMapper.listPageByRcEvaluateWithOrder(memberId);
    }

    @Override
    public List<OrderInfoVo> listByRcWithEvaluateVo(Long memberId) {
        return orderInfoMapper.listByRcWithEvaluateVo(memberId);
    }

    @Override
    public List<OrderInfo> listFinishOrder(Long memberId) {

        return  orderInfoMapper.listFinishOrder(memberId);
    }

    @Override
    public OrderInfo selectByNotEnd(Long memberId) {
        return orderInfoMapper.selectByNotEnd(memberId);
    }

    @Override
    public List<OrderInfo> listByInvoice(List<Long> ids, Long memberId) {
        return orderInfoMapper.listByInvoice(ids,memberId);
    }
}
